from django import template
from django.template import Node, NodeList, Template, Context, Variable, VariableDoesNotExist
from django.template.defaulttags import IfEqualNode
from django.template import TemplateSyntaxError

from django_utils.templatetag_helpers import resolve_variable

register = template.Library()

@register.tag(name="static_with")
def do_static_with(parser, token):
    """
    Adds a value to the context (inside of this block) for caching and easy
    access.

    For example::

        {% with person.some_sql_method as total %}
            {{ total }} object{{ total|pluralize }}
        {% endwith %}
    """
    bits = list(token.split_contents())
    if len(bits) != 5 or bits[3] != "as":
        raise TemplateSyntaxError("%r expected format is 'static_value,dynamic_value as name'" %
                                  bits)
    static_var = bits[1]
    dynamic_var = bits[2]
    name = bits[4]
    nodelist = parser.parse(('endstatic_with',))
    parser.delete_first_token()
    return StaticWithNode(static_var,  dynamic_var, name, nodelist)

class StaticWithNode(Node):
    def __init__(self, static_var, dynamic_var,  name, nodelist):
        self.static_var = static_var
        self.dynamic_var = dynamic_var
        self.name = name
        self.nodelist = nodelist

    def __repr__(self):
        return "<StaticWithNode>"

    def render(self, context):
        val = "%s%s" % (str(resolve_variable(self.static_var,  context,  self.static_var)), str(resolve_variable(self.dynamic_var,  context,  self.dynamic_var)))
        
        context.push()
        context[self.name] = val
        output = self.nodelist.render(context)
        context.pop()
        return output
        
@register.tag(name="update_context")
def do_update_context(parser,  token):
    try:
        tag_name, static_arg,  variable_arg, ass, target = token.split_contents()
        if not (static_arg[0] == static_arg[-1] and static_arg[0] in ('"', "'")):
            raise template.TemplateSyntaxError, "%r static argument should be in quotes" % tag_name
        else:
            static_arg = static_arg[1:-1]
    except ValueError:
        try:
            tag_name,  variable_arg,  ass,  target = token.split_contents()
            static_arg = None
        except ValueError:
            raise template.TemplateSyntaxError, "%r tag requires two or three arguments" % token.contents.split()[0]
    
    if not ass == 'as':
        raise template.TemplateSyntaxError, "%r has malformed arguments" % tag_name
    return UpdateContextNode(static_arg,  variable_arg,  target)

class UpdateContextNode(template.Node):
    def __init__(self,  static_arg,  variable_arg,  target):
        self.static_arg = static_arg
        self.variable_arg = Variable(variable_arg)
        self.target = target
        
    def render(self,  context):
        if self.static_arg:
            result = str(self.static_arg) + str(self.variable_arg.resolve(context))
        else:
            result = self.variable_arg.resolve(context)
        context[self.target] = result
        return ''
